﻿using System;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using HighDiveEngine.Aggregates;
using HighDiveEngine.Model;
using HighDiveEngine.Resources;
using System.Collections.Generic;

namespace HighDiveAdmin.GUI.Components
{
    /// <summary>
    /// Control that shows information about the dive that is about to be performed
    /// </summary>
    public partial class RunningContestCurrentDiveGroupBox : UserControl
    {
        /// <summary>
        /// Triggered when the admin has entered a judgescore manually
        /// </summary>
        public event DelegateVoidDoubleInt EventManualScoreEntry;
        public RunningContestCurrentDiveGroupBox()
        {
            InitializeComponent();
        }

        #region ButtonClickEvents
        private void buttonManulScoreSend_Click(object sender, EventArgs e)
        {
            if (EventManualScoreEntry == null) return;

            var rgx = new Regex(@"^((10)|([0-9]([\.\,][05])?))$");
            foreach (var txtBox in panelJudgeScores.Controls.OfType<TextBox>().Where(txtBox => txtBox.Enabled && !rgx.IsMatch(txtBox.Text)))
            {
                if (txtBox == textBoxJudgeScore1)
                    toolTipError.Show("Valid: 0-10 with 0.5 increments", textBoxJudgeScore1, 30, 22, 1500);
                else if (txtBox == textBoxJudgeScore2)
                    toolTipError.Show("Valid: 0-10 with 0.5 increments", textBoxJudgeScore2, 30, 22, 1500);
                else if (txtBox == textBoxJudgeScore3)
                    toolTipError.Show("Valid: 0-10 with 0.5 increments", textBoxJudgeScore3, 30, 22, 1500);
                else if (txtBox == textBoxJudgeScore4)
                    toolTipError.Show("Valid: 0-10 with 0.5 increments", textBoxJudgeScore4, 30, 22, 1500);
                else if (txtBox == textBoxJudgeScore5)
                    toolTipError.Show("Valid: 0-10 with 0.5 increments", textBoxJudgeScore5, 30, 22, 1500);
                else if (txtBox == textBoxJudgeScore6)
                    toolTipError.Show("Valid: 0-10 with 0.5 increments", textBoxJudgeScore6, 30, 22, 1500);
                else if (txtBox == textBoxJudgeScore7)
                    toolTipError.Show("Valid: 0-10 with 0.5 increments", textBoxJudgeScore7, 30, 22, 1500);
                return;
            }

            List<TextBox> textBoxList = new List<TextBox>();

            if (textBoxJudgeScore1.Enabled) textBoxList.Add(textBoxJudgeScore1);
            if (textBoxJudgeScore2.Enabled) textBoxList.Add(textBoxJudgeScore2);
            if (textBoxJudgeScore3.Enabled) textBoxList.Add(textBoxJudgeScore3);
            if (textBoxJudgeScore4.Enabled) textBoxList.Add(textBoxJudgeScore4);
            if (textBoxJudgeScore5.Enabled) textBoxList.Add(textBoxJudgeScore5);
            if (textBoxJudgeScore6.Enabled) textBoxList.Add(textBoxJudgeScore6);
            if (textBoxJudgeScore7.Enabled) textBoxList.Add(textBoxJudgeScore7);

            foreach (var txtBox in textBoxList)
            {
                if (txtBox == textBoxJudgeScore1)
                {
                    textBoxJudgeScore1.Enabled = false;
                    EventManualScoreEntry(Convert.ToDouble(txtBox.Text.Replace(',', '.'), CultureInfo.InvariantCulture), 1);
                }
                else if (txtBox == textBoxJudgeScore2)
                {
                    textBoxJudgeScore2.Enabled = false;
                    EventManualScoreEntry(Convert.ToDouble(txtBox.Text.Replace(',', '.'), CultureInfo.InvariantCulture), 2);
                }
                else if (txtBox == textBoxJudgeScore3)
                {
                    textBoxJudgeScore3.Enabled = false;
                    EventManualScoreEntry(Convert.ToDouble(txtBox.Text.Replace(',', '.'), CultureInfo.InvariantCulture), 3);
                }
                else if (txtBox == textBoxJudgeScore4)
                {
                    textBoxJudgeScore4.Enabled = false;
                    EventManualScoreEntry(Convert.ToDouble(txtBox.Text.Replace(',', '.'), CultureInfo.InvariantCulture), 4);
                }
                else if (txtBox == textBoxJudgeScore5)
                {
                    textBoxJudgeScore5.Enabled = false;
                    EventManualScoreEntry(Convert.ToDouble(txtBox.Text.Replace(',', '.'), CultureInfo.InvariantCulture), 5);
                }
                else if (txtBox == textBoxJudgeScore6)
                {
                    textBoxJudgeScore6.Enabled = false;
                    EventManualScoreEntry(Convert.ToDouble(txtBox.Text.Replace(',', '.'), CultureInfo.InvariantCulture), 6);
                }
                else if (txtBox == textBoxJudgeScore7)
                {
                    textBoxJudgeScore7.Enabled = false;
                    EventManualScoreEntry(Convert.ToDouble(txtBox.Text.Replace(',', '.'), CultureInfo.InvariantCulture), 7);
                }
                //txtBox.ReadOnly = true;
            }
            textBoxJudgeScore1.Focus();
            buttonManulScoreSend.Visible = panelJudgeScores.Controls.OfType<TextBox>().Any(x => x.Enabled);
        } 
        #endregion

        #region FillFunctions
        /// <summary>
        /// Updates the associated controls to reflect a judges connection status
        /// </summary>
        /// <param name="judge">The judge whos status has changed</param>
        public void UpdateJudgeConnectionStatus(Judge judge)
        {
            switch (judge.JudgeNumber)
            {
                case 1: _updateJudgeStatusLabels(labelJudgeScore1, labelJudgeStatus1, textBoxJudgeScore1, judge); break;
                case 2: _updateJudgeStatusLabels(labelJudgeScore2, labelJudgeStatus2, textBoxJudgeScore2, judge); break;
                case 3: _updateJudgeStatusLabels(labelJudgeScore3, labelJudgeStatus3, textBoxJudgeScore3, judge); break;
                case 4: _updateJudgeStatusLabels(labelJudgeScore4, labelJudgeStatus4, textBoxJudgeScore4, judge); break;
                case 5: _updateJudgeStatusLabels(labelJudgeScore5, labelJudgeStatus5, textBoxJudgeScore5, judge); break;
                case 6: _updateJudgeStatusLabels(labelJudgeScore6, labelJudgeStatus6, textBoxJudgeScore6, judge); break;
                case 7: _updateJudgeStatusLabels(labelJudgeScore7, labelJudgeStatus7, textBoxJudgeScore7, judge); break;
            }
        }

        private void _updateJudgeStatusLabels(Label judgeLabel, Label statusLabel, TextBox judgeTextBox, Judge judge)
        {
            lock (judge.Status)
            {
                statusLabel.ForeColor = judgeLabel.ForeColor = judge.Status.Color;
                statusLabel.Text = judge.Status.Text;
                judgeTextBox.Enabled = !judge.Status.Equals(JudgeStatus.Status.Connected);
            }
            buttonManulScoreSend.Visible = panelJudgeScores.Controls.OfType<TextBox>().Any(x => x.Enabled);
            toolTipCurrent.SetToolTip(judgeLabel, judge.FirstName + " " + judge.LastName);
        }

        /// <summary>
        /// Sets the amount of visible controls to reflect how many judges are in the contest
        /// </summary>
        /// <param name="judgeList">List of all the judges in the contest</param>
        public void SetNumVisibleJudges(JudgeList judgeList)
        {
            foreach (Control control in panelJudgeScores.Controls)
            {
                control.Visible = false;
                var txtBox = control as TextBox;
                if (txtBox != null)
                    txtBox.Enabled = false;
            }

            switch (judgeList.NumberOfJudges)
            {
                case 7: labelJudgeStatus7.Visible = labelJudgeScore7.Visible = textBoxJudgeScore7.Visible = true; goto case 6;
                case 6: labelJudgeStatus6.Visible = labelJudgeScore6.Visible = textBoxJudgeScore6.Visible = true; goto case 5;
                case 5: labelJudgeStatus5.Visible = labelJudgeScore5.Visible = textBoxJudgeScore5.Visible = true; goto case 4;
                case 4: labelJudgeStatus4.Visible = labelJudgeScore4.Visible = textBoxJudgeScore4.Visible = true; goto case 3;
                case 3: labelJudgeStatus3.Visible = labelJudgeScore3.Visible = textBoxJudgeScore3.Visible = true; goto case 2;
                case 2: labelJudgeStatus2.Visible = labelJudgeScore2.Visible = textBoxJudgeScore2.Visible = true; goto case 1;
                case 1: labelJudgeStatus1.Visible = labelJudgeScore1.Visible = textBoxJudgeScore1.Visible = true; break;
            }

            foreach (var judge in judgeList)
            {
                UpdateJudgeConnectionStatus(judge);
            }
        }

        /// <summary>
        /// Fills the control with all the information about the dive that is about to be performed
        /// </summary>
        /// <param name="dive">Dive about tobe performed</param>
        public void FillActiveDive(Dive dive)
        {
            foreach (var txtBox in panelJudgeScores.Controls.OfType<TextBox>())
            {
                txtBox.Text = "";
            }
            labelDiver.Text = dive.Diver.FirstName + " " + dive.Diver.LastName;
            labelDiveCode.Text = dive.DiveCode;
            labelDiveHeight.Text = dive.DiveHeight.ToString();
            labelDiveNumber.Text = dive.DiveNumber.ToString();
            labelDifficulty.Text = Convert.ToDouble(dive.Difficulty).ToString(CultureInfo.InvariantCulture);

            //HACK
            if (labelJudgeStatus1.Text != "OK" && textBoxJudgeScore1.Visible) textBoxJudgeScore1.Enabled = true;
            if (labelJudgeStatus2.Text != "OK" && textBoxJudgeScore2.Visible) textBoxJudgeScore2.Enabled = true;
            if (labelJudgeStatus3.Text != "OK" && textBoxJudgeScore3.Visible) textBoxJudgeScore3.Enabled = true;
            if (labelJudgeStatus4.Text != "OK" && textBoxJudgeScore4.Visible) textBoxJudgeScore4.Enabled = true;
            if (labelJudgeStatus5.Text != "OK" && textBoxJudgeScore5.Visible) textBoxJudgeScore5.Enabled = true;
            if (labelJudgeStatus6.Text != "OK" && textBoxJudgeScore6.Visible) textBoxJudgeScore6.Enabled = true;
            if (labelJudgeStatus7.Text != "OK" && textBoxJudgeScore7.Visible) textBoxJudgeScore7.Enabled = true;
            buttonManulScoreSend.Visible = panelJudgeScores.Controls.OfType<TextBox>().Any(x => x.Enabled);
        }

        /// <summary>
        /// Fills the appropriate textbox with the score assiged to the dive by a judge
        /// </summary>
        /// <param name="score">The score sent in by the judge</param>
        public void FillJudgeScore(DiveScore score)
        {
            switch (score.Judge.JudgeNumber)
            {
                case 1: textBoxJudgeScore1.Text = score.Score.ToString(CultureInfo.InvariantCulture); break;
                case 2: textBoxJudgeScore2.Text = score.Score.ToString(CultureInfo.InvariantCulture); break;
                case 3: textBoxJudgeScore3.Text = score.Score.ToString(CultureInfo.InvariantCulture); break;
                case 4: textBoxJudgeScore4.Text = score.Score.ToString(CultureInfo.InvariantCulture); break;
                case 5: textBoxJudgeScore5.Text = score.Score.ToString(CultureInfo.InvariantCulture); break;
                case 6: textBoxJudgeScore6.Text = score.Score.ToString(CultureInfo.InvariantCulture); break;
                case 7: textBoxJudgeScore7.Text = score.Score.ToString(CultureInfo.InvariantCulture); break;
            }
        }
        #endregion

        #region TabStop
        private void RunningContestCurrentDiveGroupBox_TabStopChanged(object sender, EventArgs e)
        {
            foreach (Control control in Controls)
                control.TabStop = TabStop;
            if (TabStop)
                textBoxJudgeScore1.Focus();
        } 
        private void RunningContestCurrentDiveGroupBox_VisibleChanged(object sender, EventArgs e)
        {
            if (Visible)
                textBoxJudgeScore1.Focus();
        }
        #endregion
    }
}
